﻿// mystructure.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include "factor.hpp"
#include "stock.hpp"
#include "utility.hpp"
#include <map>

std::mutex lockListMutex;

std::mutex* getOrCreateInstrumentLock(int& ins, std::map<int, std::mutex*>& lockList)
{
	std::lock_guard<std::mutex> lock(lockListMutex);
	std::map<int, std::mutex*>::iterator it = lockList.find(ins);
	if (it == lockList.end())
	{
		std::mutex* tmp = new std::mutex();
		lockList.emplace(ins, tmp);
		return lockList[ins];
	}

	return it->second;
}


int main()
{
	auto code = "600000.SH";
	auto date = "20200214";
	int codeint = 600000;
	int dateint = 20200214;
	auto path = "D://marketData//";
	auto mdvector=txtUtility::getDataFromTxt(path, code, date);
	std::vector<std::string> tradedays = { "20200213","20200214" };
	std::vector<int> codeList = { 000001,600000 };
	std::map<int, stock> stockList;
	std::map<int, std::mutex*> lockList;
	/*config myconfig;
	myconfig.code = 600000;
	myconfig.batchSize = 200;
	myconfig.factorSize = 74;
	myconfig.initialPosition = 100000;
	myconfig.openPara=0.003;
	myconfig.ratioPara=0.4;
	myconfig.closePara=1;
	myconfig.eachMaxAmount = 60000;
	myconfig.exposureMaxAmount = 120000;
	myconfig.eachVolumePara = 0.25;
	myconfig.maxVolumePara = 0.5;
	myconfig.holdTimePara = 1200;
	myconfig.lossPara = 0.008;
	myconfig.controlPara=1;*/
	auto myconfigVector=configUtility::getParameters();

	int localtime = 91500000;
    //on start
	for (int i = 0; i < codeList.size(); i++) {
		auto code = codeList[i];
		std::mutex* mtx = getOrCreateInstrumentLock(code, lockList);
		std::lock_guard<std::mutex>  lock(*mtx);
		std::map<int, stock>::iterator it = stockList.find(code);
		if (it == stockList.end()) {
			//初始化
			std::vector<config> myconfig;
			for (int k = 0; k < myconfigVector.size(); k++) {
				if (myconfigVector[k].code == code) {
					myconfig.push_back(myconfigVector[k]);
				}
			}
			stock s = stock(myconfig);
			stockList.emplace(code, s);
		}
		auto& mystock = stockList[code];

		if (localtime < 91500000) {
			mystock.dataPreparation(path, dateint, tradedays);
		}
		
	}


	//mock OnMarketData
	marketData lastMd;
	for (int i = 0; i < mdvector.size(); i++) {
		auto md = mdvector[i];
		auto code = md.code;
		auto date = md.date;
		auto tick = md.tick;
		std::mutex* mtx = getOrCreateInstrumentLock(code, lockList);
		std::lock_guard<std::mutex>  lock(*mtx);
		std::map<int, stock>::iterator it = stockList.find(code);
		if (it == stockList.end()){
			//初始化
			myconfig.code = code;
			stock s=stock(myconfig);
			stockList.emplace(code, s);
		}

		auto& mystock = stockList[code];
		mystock.dataPreparation(path, dateint, tradedays);
		if (mystock.myfactor.initializationSuccessful == false) {
			std::cout << "error!!!" << std::endl;
			continue;
		}

		mystock.update(lastMd);

		int initialPosition = mystock.myPositionStatus.totalinitialPosition;
		//double maxVolumeEachTimeByAmount = round(mystock.myconfig.eachMaxAmount / lastMd.lastPrice / 100.0) * 100;
		//double maxExposureByAmount = round(mystock.myconfig.exposureMaxAmount / lastMd.lastPrice / 100.0) * 100;
		//double maxVolumeEachTime = mystock.myconfig.eachVolumePara * initialPosition;
		////maxVolumeEachTime=100;


		//double maxExposure = mystock.myconfig.maxVolumePara * initialPosition;
		////maxExposure=3000;


		//maxVolumeEachTime = std::min(maxVolumeEachTime, maxVolumeEachTimeByAmount);
		//maxExposure = std::min(maxExposure, maxExposureByAmount);



		/*if (initialPosition >= 100) {
			maxVolumeEachTime = std::max(100, int(maxVolumeEachTime));
		}
		if (initialPosition >= 100) {
			maxExposure = std::max(100, int(maxExposure));
		}

		maxVolumeEachTime = floor(maxVolumeEachTime / 100) * 100;
		maxExposure = floor(maxExposure / 100) * 100;
		if (initialPosition >= 100) {
			maxVolumeEachTime = std::max(100, int(maxVolumeEachTime));
		}
		if (initialPosition >= 100) {
			maxExposure = std::max(100, int(maxExposure));
		}*/
		


	}



	
   
	
	/*factorall f = factorall(path, code, date, tradedays, true);
	auto data = txtUtility::getDataFromTxt(path, code, date);
	for (int i = 0; i < data.size(); i++) {
		auto lastMD = data[i];
		f.update(lastMD);
	}*/


	std::cout << "Hello World!\n";
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件
